﻿/*
* (c) by Andreas Kreisl
*
* Sys Monitor - Plugin: HDD
* Version: 0.1
*
* License: creative commons BY-NC-SA
*/


var mod_sysmonitor_plugin_hdd_physicaldevice = new Array();
var mod_sysmonitor_plugin_hdd_refstring = "a";

// --------------------------------------------------------------------------------
// myPlugin Variables (required!)

myPlugins["hdd"] = new Object();
myPlugins["hdd"]["name"] = getLocalizedString2("mod_sysm_plugin_hdd_name");
myPlugins["hdd"]["onlyonce"] = false;
myPlugins["hdd"]["newObject"] = function (NewSettings) { return new plugin_hdd_sensor(NewSettings); }

// --------------------------------------------------------------------------------
// The Sensore Object

function plugin_hdd_sensor(NewSettings) {
	// Required variables
	this.plugin = "hdd";
	this.settings = NewSettings;
	this.edit = plugin_hdd_edit;
	this.ReDraw = plugin_hdd_ReDraw;
	this.frame = new Frame();
	this.frame.window = main;
	this.frame.width = mod_sysmonitor_width;


	// Init Const
	this.mapping = new Object();
	for (var a in filesystem.volumes ) {
		this.mapping[filesystem.volumes[a].path] = a;
	}


	// Init Settings
	if(!this.settings.drive) this.settings.drive = filesystem.volumes[0].path;
	if(!this.settings.label) this.settings.label = "";
	if(!this.settings.color) this.settings.color = "#FFFFFF";
	if(!this.settings.barcolor) this.settings.barcolor = "#0000FF";
	if(!this.settings.updspeed) this.settings.updspeed = 25;
	if(!this.settings.alert) this.settings.alert = 5;
	if(!this.settings.baralertcolor) this.settings.baralertcolor = "#FF0000";
	if(!this.settings.enhanced) this.settings.enhanced = false;
	if(!this.settings.performance) this.settings.performance = 0;
	if(!this.settings.temperature) this.settings.temperature = 0;

	// Has moved to SMART-Plugin
	this.settings.temperature = 0;

	// The Sensor
	this.frame.onMultiClick = function ( ) { plugin_hdd_opendevice.call(obj); };
	this.drive = new class_PercentBar(this.frame,0,0,filesystem.getDisplayName( this.settings.drive ));
	this.drive.PercentColor(this.settings.color);
	this.drive.PercentBarColor(this.settings.barcolor);
	if(this.settings.label != "") this.drive.text_name.data = this.settings.label;
	if(this.drive.text_name.data == "") this.drive.text_name.data = "("+this.settings.drive+")";

	this.temp = new class_PercentBar(this.frame,0,mod_sysmonitor_size,getLocalizedString2("mod_sysm_plugin_hdd_labeltemp"));
	this.temp.PercentColor(this.settings.color);
	this.temp.PercentBarColor(this.settings.barcolor);
	this.read = new class_PercentBar(this.frame,0,mod_sysmonitor_size*2,getLocalizedString2("mod_sysm_plugin_hdd_labelread"));
	this.read.PercentColor(this.settings.color);
	this.read.PercentBarColor(this.settings.barcolor);
	this.write = new class_PercentBar(this.frame,0,mod_sysmonitor_size*3,getLocalizedString2("mod_sysm_plugin_hdd_labelwrite"));
	this.write.PercentColor(this.settings.color);
	this.write.PercentBarColor(this.settings.barcolor);

	this.activity = new Object();
	this.activity.r = 0;
	this.activity.w = 0;
	this.activity.rl = 0;
	this.activity.wl = 0;
	this.activity.rd = 0;
	this.activity.wd = 0;
	this.activity.rp = 1024*1024;
	this.activity.wp = 1024*1024;

	if(this.settings.temperature==0){
		this.temp.vOffset = mod_sysmonitor_size*3;
		this.read.vOffset = mod_sysmonitor_size*1;
		this.write.vOffset = mod_sysmonitor_size*2;
	}

	// Update Timer
	var obj = this;
	this.timer = new Timer();
	this.timer.interval = this.settings.updspeed;
	this.timer.ticking = 1;
	this.timer.onTimerFired = function ( ) { plugin_hdd_update.call(obj); };
	plugin_hdd_update.call(obj);


	// Calculating sensore height
	this.frame.height = this.drive.background.vOffset + this.drive.background.height;
	if(this.settings.temperature==1)
		this.frame.height = this.temp.background.vOffset + this.temp.background.height;
	if(this.settings.performance==1)
		this.frame.height = this.write.background.vOffset + this.write.background.height;
	return true;

// --------------------------------------------------------------------------------
// Helper Functions

	function plugin_hdd_edit() {
		var availableDrives = new Array();
		var availableDrivesValue = new Array();
		for (var a in filesystem.volumes ) {
			this.mapping[filesystem.volumes[a].path] = a;
			availableDrives[a] = filesystem.getDisplayName(filesystem.volumes[a].path);
			if(! availableDrives[a] ) availableDrives[a] = filesystem.volumes[a].path;
			availableDrivesValue[a] = filesystem.volumes[a].path;
		}

		var Drive_Edit_DialogFields = Array();
		var FieldID = -1;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_color");
		Drive_Edit_DialogFields[FieldID].type = 'color';
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.color;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_barcolor");
		Drive_Edit_DialogFields[FieldID].type = 'color';
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.barcolor;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_drive");
		Drive_Edit_DialogFields[FieldID].type = 'popup';
		Drive_Edit_DialogFields[FieldID].option = availableDrives;
		Drive_Edit_DialogFields[FieldID].optionValue = availableDrivesValue;
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.drive;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_label");
		Drive_Edit_DialogFields[FieldID].type = 'text';
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.label;
		Drive_Edit_DialogFields[FieldID].description = getLocalizedString2("mod_sysm_plugin_hdd_pref_labeldesc");

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_text");
		Drive_Edit_DialogFields[FieldID].type = 'popup';
		Drive_Edit_DialogFields[FieldID].option = new Array(getLocalizedString2("mod_sysm_plugin_hdd_pref_free"),getLocalizedString2("mod_sysm_plugin_hdd_pref_used"),getLocalizedString2("mod_sysm_plugin_hdd_pref_total"));
		Drive_Edit_DialogFields[FieldID].optionValue = new Array(0,1,2);
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.text;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_alert");
		Drive_Edit_DialogFields[FieldID].type = 'slider';
		Drive_Edit_DialogFields[FieldID].minLength = 0;
		Drive_Edit_DialogFields[FieldID].maxLength = 100;
		Drive_Edit_DialogFields[FieldID].ticks = 21;
		Drive_Edit_DialogFields[FieldID].tickLabel = new Array("0%","25%","50%","75%","100%");
		Drive_Edit_DialogFields[FieldID].description = getLocalizedString2("mod_sysm_plugin_hdd_pref_alertdesc");
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.alert;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_baralertcolor");
		Drive_Edit_DialogFields[FieldID].type = 'color';
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.baralertcolor;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_enhanced");
		Drive_Edit_DialogFields[FieldID].type = 'checkbox';
		Drive_Edit_DialogFields[FieldID].description = getLocalizedString2("mod_sysm_plugin_hdd_pref_enhanceddesc");
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.enhanced;
		if(system.platform!="windows")
			Drive_Edit_DialogFields[FieldID].hidden = 1;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_temperature");
		Drive_Edit_DialogFields[FieldID].type = 'checkbox';
		Drive_Edit_DialogFields[FieldID].description = getLocalizedString2("mod_sysm_plugin_hdd_pref_temperaturedesc");
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.temperature;
		//if(system.platform!="windows")
			Drive_Edit_DialogFields[FieldID].hidden = 1;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_hdd_pref_performance");
		Drive_Edit_DialogFields[FieldID].type = 'checkbox';
		Drive_Edit_DialogFields[FieldID].description = getLocalizedString2("mod_sysm_plugin_hdd_pref_performancedesc");
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.performance;
		if(system.platform!="windows")
			Drive_Edit_DialogFields[FieldID].hidden = 1;

		Drive_Edit_DialogFields[++FieldID] = new FormField();
		Drive_Edit_DialogFields[FieldID].title = getLocalizedString2("mod_sysm_plugin_updatespeed_label");
		Drive_Edit_DialogFields[FieldID].type = 'popup';
		Drive_Edit_DialogFields[FieldID].optionValue = new Array(1,2,3,5,10,15,20,25,30);
		Drive_Edit_DialogFields[FieldID].option = new Array();
		for(var i = 0; i < Drive_Edit_DialogFields[FieldID].optionValue.length ; i++ )
			Drive_Edit_DialogFields[FieldID].option[i] = getLocalizedString2("mod_sysm_plugin_updatespeed_" + Drive_Edit_DialogFields[FieldID].optionValue[i]);
		Drive_Edit_DialogFields[FieldID].defaultValue = this.settings.updspeed;


		var Drive_Edit_DialogResults = form(Drive_Edit_DialogFields, getLocalizedString2("mod_sysm_plugin_preftitle") + myPlugins[this.plugin]["name"]);
		if (Drive_Edit_DialogResults != null) {
			this.settings.color = Drive_Edit_DialogResults[0];
			this.drive.PercentColor(this.settings.color);
			this.temp.PercentColor(this.settings.color);
			this.read.PercentColor(this.settings.color);
			this.write.PercentColor(this.settings.color);

			this.settings.barcolor = Drive_Edit_DialogResults[1];
			this.drive.PercentBarColor(this.settings.barcolor);
			this.temp.PercentBarColor(this.settings.barcolor);
			this.read.PercentBarColor(this.settings.barcolor);
			this.write.PercentBarColor(this.settings.barcolor);

			this.settings.label = Drive_Edit_DialogResults[3];

			this.settings.drive = Drive_Edit_DialogResults[2];
			if(this.settings.label == "") this.drive.text_name.data = filesystem.getDisplayName( this.settings.drive );
			else this.drive.text_name.data = this.settings.label;
			if(this.drive.text_name.data == "") this.drive.text_name.data = "("+this.settings.drive+")";

			this.settings.text = Drive_Edit_DialogResults[4];
			this.settings.alert = Drive_Edit_DialogResults[5];
			this.settings.baralertcolor = Drive_Edit_DialogResults[6];
			this.settings.enhanced = Drive_Edit_DialogResults[7];
			this.settings.temperature = Drive_Edit_DialogResults[8];
			this.settings.performance = Drive_Edit_DialogResults[9];


			if((this.settings.performance==1) && (mod_wmi_hdd_GetDeviceR(this.settings.drive)==0)) {
				this.settings.performance=0;
				alert(getLocalizedString2("mod_sysm_plugin_hdd_noperformance"));
			}


			if((this.settings.temperature==1) && (VBSEnabled==false)) {
				this.settings.temperature=0;
				alert(getLocalizedString2("mod_sysm_plugin_vbs_required"));
			}


			if((this.settings.temperature==1) && (VBSEnabled)) {
				if(!(mod_sysmonitor_plugin_hdd_physicaldevice[this.settings.drive.substr(0,2)]>=0)) {
					if(mod_sysmonitor_debug>2) print("Search Mapping for: " + this.settings.drive.substr(0,2));
					var tmpSensores = runCommand('cscript.exe //nologo "' + mod_sysmonitor_path_physicaldevice + '"').split("\n");
					for(i=0;i<tmpSensores.length;i++) {
						var tmp = tmpSensores[i].split("=");
						mod_sysmonitor_plugin_hdd_physicaldevice[tmp[0]]=parseInt(tmp[1]);
					}
				}
				if(!(mod_sysmonitor_plugin_hdd_physicaldevice[this.settings.drive.substr(0,2)]>=0)) {
					this.settings.temperature=0;
					alert(getLocalizedString2("mod_sysm_plugin_hdd_notemperature"));
				}
			}


			if(this.settings.temperature==1){
				this.temp.vOffset = mod_sysmonitor_size*1;
				this.read.vOffset = mod_sysmonitor_size*2;
				this.write.vOffset = mod_sysmonitor_size*3;
			}else{
				this.temp.vOffset = mod_sysmonitor_size*3;
				this.read.vOffset = mod_sysmonitor_size*1;
				this.write.vOffset = mod_sysmonitor_size*2;
			}


			if ( this.settings.updspeed != Drive_Edit_DialogResults[10] ) {
				this.settings.updspeed = Drive_Edit_DialogResults[10];
				this.timer.interval = this.settings.updspeed;
			}
			this.ReDraw();
			mod_sysmonitor_ReDraw();
			plugin_hdd_update.call(this);
		}
		delete Drive_Edit_DialogFields;
		return true;
	}

	function plugin_hdd_update() {
		for (var a in this.mapping ) {
			this.mapping[a] = -1;
		}
		for (var a in filesystem.volumes ) {
			this.mapping[filesystem.volumes[a].path] = a;
		}

		if(this.mapping[this.settings.drive]>=0) {
			if(this.settings.enhanced == "1") {
				if(this.settings.label == "") this.drive.text_name.data = mod_wmi_hdd_GetVolumeName(this.settings.drive) + " (" + mod_wmi_hdd_GetName(this.settings.drive) + ")";
				else this.drive.text_name.data = this.settings.label;

				this.DriveSize = mod_wmi_hdd_GetSize(this.settings.drive);
				this.DriveFree = mod_wmi_hdd_GetFreeSpace(this.settings.drive);
			} else {
				if(this.settings.label == "") this.drive.text_name.data = filesystem.getDisplayName( this.settings.drive );
				else this.drive.text_name.data = this.settings.label;
				if(this.drive.text_name.data == "") this.drive.text_name.data = "("+this.settings.drive+")";

				this.DriveSize = filesystem.volumes[this.mapping[this.settings.drive]].totalBytes;
				this.DriveFree = filesystem.volumes[this.mapping[this.settings.drive]].freeBytes;
			}
			this.DriveValue = 100 * ( this.DriveSize - this.DriveFree ) / this.DriveSize;

			if(this.settings.text==1)
				this.drive.PercentBarValue( this.DriveValue , bytesToUIString( this.DriveSize - this.DriveFree ) );
			else if(this.settings.text==2)
				this.drive.PercentBarValue( this.DriveValue , bytesToUIString( this.DriveSize ) );
			else
				this.drive.PercentBarValue( this.DriveValue , bytesToUIString( this.DriveFree ) );

			if(this.settings.alert>0) {
				if( (100 - this.DriveValue) < this.settings.alert ) {
					this.drive.PercentBarColor(this.settings.baralertcolor);
				} else {
					this.drive.PercentBarColor(this.settings.barcolor);
				}
			}


			if((this.settings.temperature==1) && VBSEnabled) {
				if(!(mod_sysmonitor_plugin_hdd_physicaldevice[this.settings.drive.substr(0,2)]>=0)) {
					if(mod_sysmonitor_debug>2) print("Search Mapping for: " + this.settings.drive.substr(0,2));
					var tmpSensores = runCommand('cscript.exe //nologo "' + mod_sysmonitor_path_physicaldevice + '"').split("\n");
					for(i=0;i<tmpSensores.length;i++) {
						var tmp = tmpSensores[i].split("=");
						mod_sysmonitor_plugin_hdd_physicaldevice[tmp[0]]=parseInt(tmp[1]);
					}
				}

				if(mod_sysmonitor_plugin_hdd_physicaldevice[this.settings.drive.substr(0,2)]>=0) {
					var tmpSensores = runCommand('"' + mod_sysmonitor_path_smartctl + '" -A sd' + String.fromCharCode(mod_sysmonitor_plugin_hdd_refstring.charCodeAt(0) + mod_sysmonitor_plugin_hdd_physicaldevice[this.settings.drive.substr(0,2)]));
					i = tmpSensores.indexOf("194 ");
					if(i>0) {
						tmpSensores = tmpSensores.substring(i);
						i = tmpSensores.indexOf("\n");
						tmpSensores = tmpSensores.substring(0,i);
						i = tmpSensores.lastIndexOf(" ");
						tmpSensores = tmpSensores.substring(i + 1);
						this.temp.PercentBarValue(tmpSensores,tmpSensores + " °C");
					} else {
						this.temp.PercentBarValue(100,getLocalizedString2("mod_sysm_plugin_offline"));
					}
				}
			}

			if(this.settings.performance==1) {
				this.activity.r = mod_wmi_hdd_GetDeviceR(this.settings.drive);
				this.activity.w = mod_wmi_hdd_GetDeviceW(this.settings.drive);

				if(this.activity.rl == 0) this.activity.rl = this.activity.r;
				if(this.activity.wl == 0) this.activity.wl = this.activity.w;

				this.activity.rd = (this.activity.r - this.activity.rl) / this.timer.interval;
				this.activity.wd = (this.activity.w - this.activity.wl) / this.timer.interval;

				if(this.activity.rd > this.activity.rp) this.activity.rp = this.activity.rd;
				if(this.activity.wd > this.activity.wp) this.activity.wp = this.activity.wd;

				this.read.PercentBarValue( 100*this.activity.rd/this.activity.rp  ,bytesToUIString(this.activity.rd));
				this.write.PercentBarValue(100*this.activity.wd/this.activity.wp ,bytesToUIString(this.activity.wd));
			}

		} else {
			this.drive.text_name.data = "("+this.settings.drive+")";
			this.drive.PercentBarValue(100,getLocalizedString2("mod_sysm_plugin_offline"));
		}
		return true;
	}

	function plugin_hdd_opendevice() {
		filesystem.open(this.settings.drive);
		return true;
	}

	function plugin_hdd_ReDraw() {
		this.frame.width = mod_sysmonitor_width;
		this.drive.style = preferences.mod_sysmonitor_bar_style.value;
		this.drive.size = mod_sysmonitor_size;

		this.temp.style = preferences.mod_sysmonitor_bar_style.value;
		this.temp.size = mod_sysmonitor_size;

		this.read.style = preferences.mod_sysmonitor_bar_style.value;
		this.read.size = mod_sysmonitor_size;

		this.write.style = preferences.mod_sysmonitor_bar_style.value;
		this.write.size = mod_sysmonitor_size;

		if(this.settings.temperature==1){
			this.temp.vOffset = mod_sysmonitor_size*1;
			this.read.vOffset = mod_sysmonitor_size*2;
			this.write.vOffset = mod_sysmonitor_size*3;
		}else{
			this.temp.vOffset = mod_sysmonitor_size*3;
			this.read.vOffset = mod_sysmonitor_size*1;
			this.write.vOffset = mod_sysmonitor_size*2;
		}


		this.frame.height = this.drive.background.vOffset + this.drive.background.height;
		if(this.settings.temperature==1)
			this.frame.height = this.temp.background.vOffset + this.temp.background.height;
		if(this.settings.performance==1)
			this.frame.height = this.write.background.vOffset + this.write.background.height;
		return true;
	}


	function mod_wmi_hdd_GetSize(path) { 
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "Size" ).Value;
		} catch (e) { return 0; }
	}
	
	function mod_wmi_hdd_GetFreeSpace(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "FreeSpace" ).Value;
		} catch (e) { return 0; }
	}

	function mod_wmi_hdd_GetVolumeName(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "VolumeName" ).Value;
		} catch (e) { return ""; }
	}

	function mod_wmi_hdd_GetName(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
			//return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "Name" ).Value;
			return path;
		} catch (e) { return ""; }
	}

	function mod_wmi_hdd_GetVolumeSerialNumber(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "VolumeSerialNumber" ).Value;
		} catch (e) { return ""; }
	}

	function mod_wmi_hdd_GetFileSystem(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "FileSystem" ).Value;
		} catch (e) { return ""; }
	}

	function mod_wmi_hdd_GetCompressed(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_LogicalDisk="' + path + '"' ).Properties_.Item( "Compressed" ).Value;
		} catch (e) { return ""; }
	}

	function mod_wmi_hdd_GetDeviceR(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_PerfRawData_PerfDisk_LogicalDisk="' + path + '"' ).Properties_.Item( "DiskReadBytesPerSec"  ).Value;
		} catch (e) { return 0; }
	}

	function mod_wmi_hdd_GetDeviceW(path) {
		if(path.length != 2) path = path.substr(0,2);
		try {
		return wmi.Get( 'Win32_PerfRawData_PerfDisk_LogicalDisk="' + path + '"' ).Properties_.Item( "DiskWriteBytesPerSec" ).Value;
		} catch (e) { return 0; }
	}

}

// --------------------------------------------------------------------------------
// The END